package com.hehe.handler;

import com.hehe.entity.ApiResponse;
import com.hehe.powernode.constant.BusinessEnum;
import com.hehe.powernode.ex.BusinessException;
import com.hehe.powernode.model.Result;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.stream.Collectors;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

/**
 * 全局异常处理类
 */
@Slf4j
@RestControllerAdvice
//@RestControllerAdvice是Spring框架提供的一个注解，用于定义全局异常处理器和全局数据绑定设置。它结合了@ControllerAdvice和@ResponseBody两个注解的功能。
public class GlobalExceptionHandle {
    /**
     * 处理：业务异步，异常信息可以是用户看到的
     *
     * @param e
     * @return
     */
    @ExceptionHandler(BusinessException.class)
    public Result<String> businessHandler(BusinessException e) {
        e.printStackTrace();
        log.error("AccessDeniedException BusinessException:{}", e.getMessage());
        return Result.fail(BusinessEnum.OPERATION_FAIL.getCode(), e.getMessage());
    }

    /**
     * 处理：服务运行时异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(RuntimeException.class)
    public Result<String> runtimeException(RuntimeException e) {
        e.printStackTrace();
        log.error("AccessDeniedException RuntimeException:{}", e.getMessage());
        return Result.fail(BusinessEnum.SERVER_INNER_ERROR);
    }

    /**
     * 处理：权限不足异常
     *
     * @param e
     * @throws AccessDeniedException
     */
    @ExceptionHandler(AccessDeniedException.class)
    public void accessDeniedException(AccessDeniedException e) throws AccessDeniedException {
        e.printStackTrace();
        log.error("AccessDeniedException errorMessage:{}", e.getMessage());
        // 抛出AccessDeniedException异常，走自定义AccessDeniedException异常处理
        throw e;
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ApiResponse<String>> handleValidationExceptions(MethodArgumentNotValidException ex) {
        String errorMessage = ex.getBindingResult().getFieldErrors()
                .stream()
                .map(error -> error.getDefaultMessage())
                .collect(Collectors.joining(", "));
        ex.printStackTrace();
        log.error("GlobalExceptionHandler errorMessage:{}", errorMessage);
        return new ResponseEntity<>(ApiResponse.error(errorMessage), HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(MissingServletRequestParameterException.class)
    public ResponseEntity<ApiResponse<String>> handleMissingParams(MissingServletRequestParameterException ex) {
        ex.printStackTrace();
        String errorMessage = "缺少请求参数: " + ex.getParameterName();
        log.error("GlobalExceptionHandler2 errorMessage:{}", errorMessage);
        return new ResponseEntity<>(ApiResponse.error(errorMessage), HttpStatus.BAD_REQUEST);
    }
}
